package jparchess.engine;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.lang.*;

public class MoveGenerator {
    // knight
    static final int MOVE_KNIGHT_UPPER_RIGHT1 = 17;
    static final int MOVE_KNIGHT_UPPER_RIGHT2 = 10;
    static final int MOVE_KNIGHT_LOWER_RIGHT1 = -15;
    static final int MOVE_KNIGHT_LOWER_RIGHT2 = -6;
    static final int MOVE_KNIGHT_UPPER_LEFT1 = 15;
    static final int MOVE_KNIGHT_UPPER_LEFT2 = 6;
    static final int MOVE_KNIGHT_LOWER_LEFT1 = -17;
    static final int MOVE_KNIGHT_LOWER_LEFT2 = -10;  
    
    
    // use tables for KNIGHT_ATTACKS and KING_ATTACKS ( due to jumping off board and landing somewhere else also )
    static final int[][] MOVE_KNIGHT = new int[64][8+1]; // [board index][move index + end code]
    static final int[][] MOVE_KING = new int[64][8+1]; // [board index][move index + end code]
    static final int[][] MOVE_WP = new int[64][4+1]; // [board index][move index + end code]
    static final int[][] MOVE_WP_ATTACK = new int[64][4+1]; // [board index][move index + end code]
    static final int[][] MOVE_BP = new int[64][4+1]; // [board index][move index + end code]
    static final int[][] MOVE_BP_ATTACK = new int[64][4+1]; // [board index][move index + end code]
    
    static final int[] MOVE_KNIGHT_ARRAY =
    	{MOVE_KNIGHT_UPPER_RIGHT1, MOVE_KNIGHT_UPPER_RIGHT2, MOVE_KNIGHT_LOWER_RIGHT1, MOVE_KNIGHT_LOWER_RIGHT2,
    	 MOVE_KNIGHT_UPPER_LEFT1, MOVE_KNIGHT_UPPER_LEFT2, MOVE_KNIGHT_LOWER_LEFT1, MOVE_KNIGHT_LOWER_LEFT2};
    
    // sliding pieces (diagonals)
    static final int[] MOVE_DIAG_LOWER_LEFT_ARRAY = {-9, -18, -27, -36, -45, -54, -63};
    static final int[] MOVE_DIAG_UPPER_RIGHT_ARRAY = {9, 18, 27, 36, 45, 54, 63};
    static final int[] MOVE_DIAG_LOWER_RIGHT_ARRAY = {-7, -14, -21, -28, -35, -42, -49};
    static final int[] MOVE_DIAG_UPPER_LEFT_ARRAY = {7, 14, 21, 28, 35, 42, 49};
    // sliding pieces (vertical)
    static final int[] MOVE_UP_ARRAY = {8, 16, 24, 32, 40, 48, 56};
    static final int[] MOVE_DOWN_ARRAY = {-8, -16, -24, -32, -40, -48, -56};
    static final int MOVE_RIGHT = 1;
    static final int MOVE_LEFT = -1;
    //static final int[] MOVE_RIGHT_ARRAY = {1, 2, 3, 4, 5, -48, -56};
    // horizontal must check if rank is still same
    
    static final int[] MOVE_KING_ARRAY = {MOVE_DIAG_UPPER_LEFT_ARRAY[0], MOVE_UP_ARRAY[0], MOVE_DIAG_UPPER_RIGHT_ARRAY[0],
    									  MOVE_LEFT, MOVE_RIGHT,
    									  MOVE_DIAG_LOWER_LEFT_ARRAY[0], MOVE_DOWN_ARRAY[0], MOVE_DIAG_LOWER_RIGHT_ARRAY[0]};
    
    // generic moveToValid for all pieces using add offset constants
    public boolean moveValid(int pos, int add) {
    	if (((pos+add) >= D.A1) && ((pos+add) <= D.H8)) return true; else return false;
    }
	
	// check if moves are valid within board boundaries
    // special pawn move methods give tiny speed up
	public boolean moveUp(int pos) {				
		if ((pos+MOVE_UP_ARRAY[0]) <= D.H8) return true; else return false;				
	}
	public boolean move2Up(int pos) {				
		if ((pos+MOVE_UP_ARRAY[1]) <= D.H4) return true; else return false;				
	}
	public boolean moveDiagUpperRight(int pos) {				
		if ((pos+MOVE_DIAG_UPPER_RIGHT_ARRAY[0]) <= D.H8) return true; else return false;				
	}
	public boolean moveDiagUpperLeft(int pos) {				
		if ((pos+MOVE_DIAG_UPPER_LEFT_ARRAY[0]) <= D.H8) return true; else return false;				
	}
	public boolean moveDown(int pos) {				
		if ((pos+MOVE_DOWN_ARRAY[0]) >= D.A1) return true; else return false;				
	}
	public boolean move2Down(int pos) {				
		if ((pos+MOVE_DOWN_ARRAY[1]) >= D.A5) return true; else return false;				
	}
	public boolean moveDiagLowerRight(int pos) {				
		if ((pos+MOVE_DIAG_LOWER_RIGHT_ARRAY[0]) >= D.A1) return true; else return false;				
	}
	public boolean moveDiagLowerLeft(int pos) {				
		if ((pos+MOVE_DIAG_LOWER_LEFT_ARRAY[0]) >= D.A1) return true; else return false;				
	}
	
	public boolean isEmpty(int pos) {
		if (board.square[pos] == D.EMPTY) return true; else return false;
	}
	public boolean isBlackPiece(int piece) {
		if (piece < D.EMPTY) return true; else return false;
	}
	public boolean isWhitePiece(int piece) {
		if (piece > D.EMPTY) return true; else return false;
	}
	public boolean noPawnPromotionSquareForWhite(int pos) {
		if (pos >= D.A8 && pos <= D.H8) return false; 
		else return true;
	}
	public boolean noPawnPromotionSquareForBlack(int pos) {
		if (pos >= D.A1 && pos <= D.H1) return false; 
		else return true;
	}
	
	public boolean positivFileDifference(int pos, int add) {
		if (((pos+add) % 8) - (pos % 8) > 0) return true; else return false;
	}
	
	public boolean sameRank(int pos, int add) {
		if ((pos / 8) == ((pos+add) / 8)) return true; else return false;
	}

	// TODO
	private boolean notAttacked(int i, boolean sideToMove) {
		// TODO Auto-generated method stub
		return true;
	}

	Board board; // same board, cause it's a reference to the initially created board object // java passes object references by value
	public ArrayList<Move> moveList = new ArrayList<Move>(); // maybe resize to reserve mem for faster run (JVM)
	// http://www.oracle.com/technetwork/java/javase/tech/memorymanagement-whitepaper-1-150020.pdf
	
	public void setBoard(Board board) {
		this.board = board;
	}
	
	
	// table-based access to king attacks
	public void createKingAttacks() {
		for (int i=D.A1; i <= D.H8; i++) {
			MOVE_KING[i][0] = i+MOVE_UP_ARRAY[0];
			MOVE_KING[i][1] = i+MOVE_DOWN_ARRAY[0];
			MOVE_KING[i][2] = i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0];
			MOVE_KING[i][3] = i+MOVE_DIAG_UPPER_LEFT_ARRAY[0];
			MOVE_KING[i][4] = i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0];
			MOVE_KING[i][5] = i+MOVE_DIAG_LOWER_LEFT_ARRAY[0];
			MOVE_KING[i][6] = i+MOVE_LEFT;
			MOVE_KING[i][7] = i+MOVE_RIGHT;
			MOVE_KING[i][8] = -1;
		}
		
		// restriction on border
		MOVE_KING[D.A1][0] = D.A2; MOVE_KING[D.A1][1] = D.B2; MOVE_KING[D.A1][2] = D.B1; MOVE_KING[D.A1][3] = -1;
		MOVE_KING[D.H1][0] = D.H2; MOVE_KING[D.H1][1] = D.G2; MOVE_KING[D.H1][2] = D.G1; MOVE_KING[D.H1][3] = -1;
		MOVE_KING[D.A8][0] = D.B8; MOVE_KING[D.A8][1] = D.B7; MOVE_KING[D.A8][2] = D.A7; MOVE_KING[D.A1][3] = -1;
		MOVE_KING[D.H8][0] = D.H7; MOVE_KING[D.H8][1] = D.G7; MOVE_KING[D.H8][2] = D.G8; MOVE_KING[D.H8][3] = -1;
		
		MOVE_KING[D.A2][0] = D.A3; MOVE_KING[D.A2][1] = D.B3; MOVE_KING[D.A2][2] = D.B2; MOVE_KING[D.A2][3] = D.B1; MOVE_KING[D.A2][4] = D.A1; MOVE_KING[D.A2][5] = -1;
		MOVE_KING[D.A3][0] = D.A4; MOVE_KING[D.A3][1] = D.B4; MOVE_KING[D.A3][2] = D.B3; MOVE_KING[D.A3][3] = D.B2; MOVE_KING[D.A3][4] = D.A2; MOVE_KING[D.A3][5] = -1;
		MOVE_KING[D.A4][0] = D.A5; MOVE_KING[D.A4][1] = D.B5; MOVE_KING[D.A4][2] = D.B4; MOVE_KING[D.A4][3] = D.B3; MOVE_KING[D.A4][4] = D.A3; MOVE_KING[D.A4][5] = -1;
		MOVE_KING[D.A5][0] = D.A6; MOVE_KING[D.A5][1] = D.B6; MOVE_KING[D.A5][2] = D.B5; MOVE_KING[D.A5][3] = D.B4; MOVE_KING[D.A5][4] = D.A4; MOVE_KING[D.A5][5] = -1;
		MOVE_KING[D.A6][0] = D.A7; MOVE_KING[D.A6][1] = D.B7; MOVE_KING[D.A6][2] = D.B6; MOVE_KING[D.A6][3] = D.B5; MOVE_KING[D.A6][4] = D.A5; MOVE_KING[D.A6][5] = -1;
		MOVE_KING[D.A7][0] = D.A8; MOVE_KING[D.A7][1] = D.B8; MOVE_KING[D.A7][2] = D.B7; MOVE_KING[D.A7][3] = D.B6; MOVE_KING[D.A7][4] = D.A6; MOVE_KING[D.A7][5] = -1;
		
		MOVE_KING[D.H2][0] = D.H3; MOVE_KING[D.H2][1] = D.G3; MOVE_KING[D.H2][2] = D.G2; MOVE_KING[D.H2][3] = D.G1; MOVE_KING[D.H2][4] = D.H1; MOVE_KING[D.H2][5] = -1;
		MOVE_KING[D.H3][0] = D.H4; MOVE_KING[D.H3][1] = D.G4; MOVE_KING[D.H3][2] = D.G3; MOVE_KING[D.H3][3] = D.G2; MOVE_KING[D.H3][4] = D.H2; MOVE_KING[D.H3][5] = -1;
		MOVE_KING[D.H4][0] = D.H5; MOVE_KING[D.H4][1] = D.G5; MOVE_KING[D.H4][2] = D.G4; MOVE_KING[D.H4][3] = D.G3; MOVE_KING[D.H4][4] = D.H3; MOVE_KING[D.H4][5] = -1;
		MOVE_KING[D.H5][0] = D.H6; MOVE_KING[D.H5][1] = D.G6; MOVE_KING[D.H5][2] = D.G5; MOVE_KING[D.H5][3] = D.G4; MOVE_KING[D.H5][4] = D.H4; MOVE_KING[D.H5][5] = -1;
		MOVE_KING[D.H6][0] = D.H7; MOVE_KING[D.H6][1] = D.G7; MOVE_KING[D.H6][2] = D.G6; MOVE_KING[D.H6][3] = D.G5; MOVE_KING[D.H6][4] = D.H5; MOVE_KING[D.H6][5] = -1;
		MOVE_KING[D.H7][0] = D.H8; MOVE_KING[D.H7][1] = D.G8; MOVE_KING[D.H7][2] = D.G7; MOVE_KING[D.H7][3] = D.G6; MOVE_KING[D.H7][4] = D.H6; MOVE_KING[D.H7][5] = -1;
		
		MOVE_KING[D.B1][0] = D.B2; MOVE_KING[D.B1][1] = D.C2; MOVE_KING[D.B1][2] = D.C1; MOVE_KING[D.B1][3] = D.A1; MOVE_KING[D.B1][4] = D.A2; MOVE_KING[D.B1][5] = -1;
		MOVE_KING[D.C1][0] = D.C2; MOVE_KING[D.C1][1] = D.D2; MOVE_KING[D.C1][2] = D.D1; MOVE_KING[D.C1][3] = D.B1; MOVE_KING[D.C1][4] = D.B2; MOVE_KING[D.C1][5] = -1;
		MOVE_KING[D.D1][0] = D.D2; MOVE_KING[D.D1][1] = D.E2; MOVE_KING[D.D1][2] = D.E1; MOVE_KING[D.D1][3] = D.C1; MOVE_KING[D.D1][4] = D.C2; MOVE_KING[D.D1][5] = -1;
		MOVE_KING[D.E1][0] = D.E2; MOVE_KING[D.E1][1] = D.F2; MOVE_KING[D.E1][2] = D.F1; MOVE_KING[D.E1][3] = D.D1; MOVE_KING[D.E1][4] = D.D2; MOVE_KING[D.E1][5] = -1;
		MOVE_KING[D.F1][0] = D.F2; MOVE_KING[D.F1][1] = D.G2; MOVE_KING[D.F1][2] = D.G1; MOVE_KING[D.F1][3] = D.E1; MOVE_KING[D.F1][4] = D.E2; MOVE_KING[D.F1][5] = -1;
		MOVE_KING[D.G1][0] = D.G2; MOVE_KING[D.G1][1] = D.H2; MOVE_KING[D.G1][2] = D.H1; MOVE_KING[D.G1][3] = D.F1; MOVE_KING[D.G1][4] = D.F2; MOVE_KING[D.G1][5] = -1;
		
		MOVE_KING[D.B8][0] = D.B7; MOVE_KING[D.B8][1] = D.C8; MOVE_KING[D.B8][2] = D.C7; MOVE_KING[D.B8][3] = D.A7; MOVE_KING[D.B8][4] = D.A8; MOVE_KING[D.B8][5] = -1;
		MOVE_KING[D.C8][0] = D.C7; MOVE_KING[D.C8][1] = D.D8; MOVE_KING[D.C8][2] = D.D7; MOVE_KING[D.C8][3] = D.B7; MOVE_KING[D.C8][4] = D.B8; MOVE_KING[D.C8][5] = -1;
		MOVE_KING[D.D8][0] = D.D7; MOVE_KING[D.D8][1] = D.E8; MOVE_KING[D.D8][2] = D.E7; MOVE_KING[D.D8][3] = D.C7; MOVE_KING[D.D8][4] = D.C8; MOVE_KING[D.D8][5] = -1;
		MOVE_KING[D.E8][0] = D.E7; MOVE_KING[D.E8][1] = D.F8; MOVE_KING[D.E8][2] = D.F7; MOVE_KING[D.E8][3] = D.D7; MOVE_KING[D.E8][4] = D.D8; MOVE_KING[D.E8][5] = -1;
		MOVE_KING[D.F8][0] = D.F7; MOVE_KING[D.F8][1] = D.G8; MOVE_KING[D.F8][2] = D.G7; MOVE_KING[D.F8][3] = D.E7; MOVE_KING[D.F8][4] = D.E8; MOVE_KING[D.F8][5] = -1;
		MOVE_KING[D.G8][0] = D.G7; MOVE_KING[D.G8][1] = D.H8; MOVE_KING[D.G8][2] = D.H7; MOVE_KING[D.G8][3] = D.F7; MOVE_KING[D.G8][4] = D.F8; MOVE_KING[D.G8][5] = -1;
		
//		for (int i=DEF.A1; i <= DEF.H8; i++) {
//			int m= 0;
//			System.out.println(DEF.squareName[i] + "square has move to");
//			while (MOVE_KING[i][m] >= 0){
//				System.out.print(DEF.squareName[MOVE_KING[i][m]]+ " and ");
//				System.out.println();
//				m++;
//			}
//		}
	}
	
	// table-based access to knight attacks
	public void createKnightAttacks() {
		MOVE_KNIGHT[D.A1][0] = D.B3; MOVE_KNIGHT[D.A1][1] = D.C2; MOVE_KNIGHT[D.A1][2] = -1;
		MOVE_KNIGHT[D.B1][0] = D.A3; MOVE_KNIGHT[D.B1][1] = D.C3; MOVE_KNIGHT[D.B1][2] = D.D2; MOVE_KNIGHT[D.B1][3] = -1;
		MOVE_KNIGHT[D.C1][0] = D.A2; MOVE_KNIGHT[D.C1][1] = D.B3; MOVE_KNIGHT[D.C1][2] = D.D3; MOVE_KNIGHT[D.C1][3] = D.E2; MOVE_KNIGHT[D.C1][4] = -1;
		MOVE_KNIGHT[D.D1][0] = D.B2; MOVE_KNIGHT[D.D1][1] = D.C3; MOVE_KNIGHT[D.D1][2] = D.E3; MOVE_KNIGHT[D.D1][3] = D.F2; MOVE_KNIGHT[D.D1][4] = -1;
		MOVE_KNIGHT[D.E1][0] = D.C2; MOVE_KNIGHT[D.E1][1] = D.D3; MOVE_KNIGHT[D.E1][2] = D.F3; MOVE_KNIGHT[D.E1][3] = D.G2; MOVE_KNIGHT[D.E1][4] = -1;
		MOVE_KNIGHT[D.F1][0] = D.D2; MOVE_KNIGHT[D.F1][1] = D.E3; MOVE_KNIGHT[D.F1][2] = D.G3; MOVE_KNIGHT[D.F1][3] = D.H2; MOVE_KNIGHT[D.F1][4] = -1;
		MOVE_KNIGHT[D.G1][0] = D.E2; MOVE_KNIGHT[D.G1][1] = D.F3; MOVE_KNIGHT[D.G1][2] = D.H3; MOVE_KNIGHT[D.G1][3] = -1;
		MOVE_KNIGHT[D.H1][0] = D.F2; MOVE_KNIGHT[D.H1][1] = D.G3; MOVE_KNIGHT[D.H1][2] = -1;	
		
		MOVE_KNIGHT[D.A2][0] = D.B4; MOVE_KNIGHT[D.A2][1] = D.C3; MOVE_KNIGHT[D.A2][2] = D.C1; MOVE_KNIGHT[D.A2][3] = -1;
		MOVE_KNIGHT[D.B2][0] = D.A4; MOVE_KNIGHT[D.B2][1] = D.C4; MOVE_KNIGHT[D.B2][2] = D.D3; MOVE_KNIGHT[D.B2][3] = D.D1; MOVE_KNIGHT[D.B2][4] = -1;
		MOVE_KNIGHT[D.C2][0] = D.A3; MOVE_KNIGHT[D.C2][1] = D.B4; MOVE_KNIGHT[D.C2][2] = D.D4; MOVE_KNIGHT[D.C2][3] = D.E3; 
				MOVE_KNIGHT[D.C2][4] = D.E1; MOVE_KNIGHT[D.C2][5] = D.A1; MOVE_KNIGHT[D.C2][6] = -1;
		MOVE_KNIGHT[D.D2][0] = D.B3; MOVE_KNIGHT[D.D2][1] = D.C4; MOVE_KNIGHT[D.D2][2] = D.E4; MOVE_KNIGHT[D.D2][3] = D.F3; 
				MOVE_KNIGHT[D.D2][4] = D.F1; MOVE_KNIGHT[D.D2][5] = D.B1; MOVE_KNIGHT[D.D2][6] = -1;
		MOVE_KNIGHT[D.E2][0] = D.C3; MOVE_KNIGHT[D.E2][1] = D.D4; MOVE_KNIGHT[D.E2][2] = D.F4; MOVE_KNIGHT[D.E2][3] = D.G3; 
				MOVE_KNIGHT[D.E2][4] = D.G1; MOVE_KNIGHT[D.E2][5] = D.C1; MOVE_KNIGHT[D.E2][6] = -1;
		MOVE_KNIGHT[D.F2][0] = D.D3; MOVE_KNIGHT[D.F2][1] = D.E4; MOVE_KNIGHT[D.F2][2] = D.G4; MOVE_KNIGHT[D.F2][3] = D.H3; 
				MOVE_KNIGHT[D.F2][4] = D.H1; MOVE_KNIGHT[D.F2][5] = D.D1; MOVE_KNIGHT[D.F2][6] = -1;			
		MOVE_KNIGHT[D.G2][0] = D.E1; MOVE_KNIGHT[D.G2][1] = D.E3; MOVE_KNIGHT[D.G2][2] = D.F4; MOVE_KNIGHT[D.G2][3] = D.H4; MOVE_KNIGHT[D.G2][4] = -1;
		MOVE_KNIGHT[D.H2][0] = D.F1; MOVE_KNIGHT[D.H2][1] = D.F3; MOVE_KNIGHT[D.H2][2] = D.G4; MOVE_KNIGHT[D.H2][3] = -1;
		
		MOVE_KNIGHT[D.A3][0] = D.B5; MOVE_KNIGHT[D.A3][1] = D.C4; MOVE_KNIGHT[D.A3][2] = D.C2; MOVE_KNIGHT[D.A3][3] = D.B1; MOVE_KNIGHT[D.A3][4] = -1;
		MOVE_KNIGHT[D.B3][0] = D.A5; MOVE_KNIGHT[D.B3][1] = D.C5; MOVE_KNIGHT[D.B3][2] = D.D4; MOVE_KNIGHT[D.B3][3] = D.D2;		
			MOVE_KNIGHT[D.B3][4] = D.C1; MOVE_KNIGHT[D.B3][5] = D.A1; MOVE_KNIGHT[D.B3][6] = -1;			
		MOVE_KNIGHT[D.C3][0] = D.A4; MOVE_KNIGHT[D.C3][1] = D.B5; MOVE_KNIGHT[D.C3][2] = D.D5; MOVE_KNIGHT[D.C3][3] = D.E4;
			MOVE_KNIGHT[D.C3][4] = D.E2; MOVE_KNIGHT[D.C3][5] = D.D1; MOVE_KNIGHT[D.C3][6] = D.B1; MOVE_KNIGHT[D.C3][7] = D.A2; MOVE_KNIGHT[D.C3][8] = -1;
		MOVE_KNIGHT[D.D3][0] = D.B4; MOVE_KNIGHT[D.D3][1] = D.C5; MOVE_KNIGHT[D.D3][2] = D.E5; MOVE_KNIGHT[D.D3][3] = D.F4;
			MOVE_KNIGHT[D.D3][4] = D.F2; MOVE_KNIGHT[D.D3][5] = D.E1; MOVE_KNIGHT[D.D3][6] = D.C1; MOVE_KNIGHT[D.D3][7] = D.B2; MOVE_KNIGHT[D.D3][8] = -1;	
		MOVE_KNIGHT[D.E3][0] = D.C4; MOVE_KNIGHT[D.E3][1] = D.D5; MOVE_KNIGHT[D.E3][2] = D.F5; MOVE_KNIGHT[D.E3][3] = D.G4;
			MOVE_KNIGHT[D.E3][4] = D.G2; MOVE_KNIGHT[D.E3][5] = D.F1; MOVE_KNIGHT[D.E3][6] = D.D1; MOVE_KNIGHT[D.E3][7] = D.C2; MOVE_KNIGHT[D.E3][8] = -1;
		MOVE_KNIGHT[D.F3][0] = D.D4; MOVE_KNIGHT[D.F3][1] = D.E5; MOVE_KNIGHT[D.F3][2] = D.G5; MOVE_KNIGHT[D.F3][3] = D.H4;
			MOVE_KNIGHT[D.F3][4] = D.H2; MOVE_KNIGHT[D.F3][5] = D.G1; MOVE_KNIGHT[D.F3][6] = D.E1; MOVE_KNIGHT[D.F3][7] = D.D2; MOVE_KNIGHT[D.F3][8] = -1;		
		MOVE_KNIGHT[D.G3][0] = D.E4; MOVE_KNIGHT[D.G3][1] = D.F5; MOVE_KNIGHT[D.G3][2] = D.H5; MOVE_KNIGHT[D.G3][3] = D.H1;		
			MOVE_KNIGHT[D.G3][4] = D.F1; MOVE_KNIGHT[D.G3][5] = D.E2; MOVE_KNIGHT[D.G3][6] = -1;
		MOVE_KNIGHT[D.H3][0] = D.F4; MOVE_KNIGHT[D.H3][1] = D.G5; MOVE_KNIGHT[D.H3][2] = D.G1; MOVE_KNIGHT[D.H3][3] = D.F2; MOVE_KNIGHT[D.H3][4] = -1;

		MOVE_KNIGHT[D.A4][0] = D.B6; MOVE_KNIGHT[D.A4][1] = D.C5; MOVE_KNIGHT[D.A4][2] = D.C3; MOVE_KNIGHT[D.A4][3] = D.B2; MOVE_KNIGHT[D.A4][4] = -1;
		MOVE_KNIGHT[D.B4][0] = D.A6; MOVE_KNIGHT[D.B4][1] = D.C6; MOVE_KNIGHT[D.B4][2] = D.D5; MOVE_KNIGHT[D.B4][3] = D.D3;		
			MOVE_KNIGHT[D.B4][4] = D.C2; MOVE_KNIGHT[D.B4][5] = D.A2; MOVE_KNIGHT[D.B4][6] = -1;			
		MOVE_KNIGHT[D.C4][0] = D.A5; MOVE_KNIGHT[D.C4][1] = D.B6; MOVE_KNIGHT[D.C4][2] = D.D6; MOVE_KNIGHT[D.C4][3] = D.E5;
			MOVE_KNIGHT[D.C4][4] = D.E3; MOVE_KNIGHT[D.C4][5] = D.D2; MOVE_KNIGHT[D.C4][6] = D.B2; MOVE_KNIGHT[D.C4][7] = D.A3; MOVE_KNIGHT[D.C4][8] = -1;
		MOVE_KNIGHT[D.D4][0] = D.B5; MOVE_KNIGHT[D.D4][1] = D.C6; MOVE_KNIGHT[D.D4][2] = D.E6; MOVE_KNIGHT[D.D4][3] = D.F5;
			MOVE_KNIGHT[D.D4][4] = D.F3; MOVE_KNIGHT[D.D4][5] = D.E2; MOVE_KNIGHT[D.D4][6] = D.C2; MOVE_KNIGHT[D.D4][7] = D.B3; MOVE_KNIGHT[D.D4][8] = -1;	
		MOVE_KNIGHT[D.E4][0] = D.C5; MOVE_KNIGHT[D.E4][1] = D.D6; MOVE_KNIGHT[D.E4][2] = D.F6; MOVE_KNIGHT[D.E4][3] = D.G5;
			MOVE_KNIGHT[D.E4][4] = D.G3; MOVE_KNIGHT[D.E4][5] = D.F2; MOVE_KNIGHT[D.E4][6] = D.D2; MOVE_KNIGHT[D.E4][7] = D.C3; MOVE_KNIGHT[D.E4][8] = -1;
		MOVE_KNIGHT[D.F4][0] = D.D5; MOVE_KNIGHT[D.F4][1] = D.E6; MOVE_KNIGHT[D.F4][2] = D.G6; MOVE_KNIGHT[D.F4][3] = D.H5;
			MOVE_KNIGHT[D.F4][4] = D.H3; MOVE_KNIGHT[D.F4][5] = D.G2; MOVE_KNIGHT[D.F4][6] = D.E2; MOVE_KNIGHT[D.F4][7] = D.D3; MOVE_KNIGHT[D.F4][8] = -1;		
		MOVE_KNIGHT[D.G4][0] = D.E5; MOVE_KNIGHT[D.G4][1] = D.F6; MOVE_KNIGHT[D.G4][2] = D.H6; MOVE_KNIGHT[D.G4][3] = D.H2;		
			MOVE_KNIGHT[D.G4][4] = D.F2; MOVE_KNIGHT[D.G4][5] = D.E3; MOVE_KNIGHT[D.G4][6] = -1;
		MOVE_KNIGHT[D.H4][0] = D.F5; MOVE_KNIGHT[D.H4][1] = D.G6; MOVE_KNIGHT[D.H4][2] = D.G2; MOVE_KNIGHT[D.H4][3] = D.F3; MOVE_KNIGHT[D.H4][4] = -1;
		
		MOVE_KNIGHT[D.A5][0] = D.B7; MOVE_KNIGHT[D.A5][1] = D.C6; MOVE_KNIGHT[D.A5][2] = D.C4; MOVE_KNIGHT[D.A5][3] = D.B3; MOVE_KNIGHT[D.A5][4] = -1;
		MOVE_KNIGHT[D.B5][0] = D.A7; MOVE_KNIGHT[D.B5][1] = D.C7; MOVE_KNIGHT[D.B5][2] = D.D6; MOVE_KNIGHT[D.B5][3] = D.D4;		
			MOVE_KNIGHT[D.B5][4] = D.C3; MOVE_KNIGHT[D.B5][5] = D.A3; MOVE_KNIGHT[D.B5][6] = -1;			
		MOVE_KNIGHT[D.C5][0] = D.A6; MOVE_KNIGHT[D.C5][1] = D.B7; MOVE_KNIGHT[D.C5][2] = D.D7; MOVE_KNIGHT[D.C5][3] = D.E6;
			MOVE_KNIGHT[D.C5][4] = D.E4; MOVE_KNIGHT[D.C5][5] = D.D3; MOVE_KNIGHT[D.C5][6] = D.B3; MOVE_KNIGHT[D.C5][7] = D.A4; MOVE_KNIGHT[D.C5][8] = -1;
		MOVE_KNIGHT[D.D5][0] = D.B6; MOVE_KNIGHT[D.D5][1] = D.C7; MOVE_KNIGHT[D.D5][2] = D.E7; MOVE_KNIGHT[D.D5][3] = D.F6;
			MOVE_KNIGHT[D.D5][4] = D.F4; MOVE_KNIGHT[D.D5][5] = D.E3; MOVE_KNIGHT[D.D5][6] = D.C3; MOVE_KNIGHT[D.D5][7] = D.B4; MOVE_KNIGHT[D.D5][8] = -1;	
		MOVE_KNIGHT[D.E5][0] = D.C6; MOVE_KNIGHT[D.E5][1] = D.D7; MOVE_KNIGHT[D.E5][2] = D.F7; MOVE_KNIGHT[D.E5][3] = D.G6;
			MOVE_KNIGHT[D.E5][4] = D.G4; MOVE_KNIGHT[D.E5][5] = D.F3; MOVE_KNIGHT[D.E5][6] = D.D3; MOVE_KNIGHT[D.E5][7] = D.C4; MOVE_KNIGHT[D.E5][8] = -1;
		MOVE_KNIGHT[D.F5][0] = D.D6; MOVE_KNIGHT[D.F5][1] = D.E7; MOVE_KNIGHT[D.F5][2] = D.G7; MOVE_KNIGHT[D.F5][3] = D.H6;
			MOVE_KNIGHT[D.F5][4] = D.H4; MOVE_KNIGHT[D.F5][5] = D.G3; MOVE_KNIGHT[D.F5][6] = D.E3; MOVE_KNIGHT[D.F5][7] = D.D4; MOVE_KNIGHT[D.F5][8] = -1;		
		MOVE_KNIGHT[D.G5][0] = D.E6; MOVE_KNIGHT[D.G5][1] = D.F7; MOVE_KNIGHT[D.G5][2] = D.H7; MOVE_KNIGHT[D.G5][3] = D.H3;		
			MOVE_KNIGHT[D.G5][4] = D.F3; MOVE_KNIGHT[D.G5][5] = D.E4; MOVE_KNIGHT[D.G5][6] = -1;
		MOVE_KNIGHT[D.H5][0] = D.F6; MOVE_KNIGHT[D.H5][1] = D.G7; MOVE_KNIGHT[D.H5][2] = D.G3; MOVE_KNIGHT[D.H5][3] = D.F4; MOVE_KNIGHT[D.H5][4] = -1;
		
		MOVE_KNIGHT[D.A6][0] = D.B8; MOVE_KNIGHT[D.A6][1] = D.C7; MOVE_KNIGHT[D.A6][2] = D.C5; MOVE_KNIGHT[D.A6][3] = D.B4; MOVE_KNIGHT[D.A6][4] = -1;
		MOVE_KNIGHT[D.B6][0] = D.A8; MOVE_KNIGHT[D.B6][1] = D.C8; MOVE_KNIGHT[D.B6][2] = D.D7; MOVE_KNIGHT[D.B6][3] = D.D5;		
			MOVE_KNIGHT[D.B6][4] = D.C4; MOVE_KNIGHT[D.B6][5] = D.A4; MOVE_KNIGHT[D.B6][6] = -1;			
		MOVE_KNIGHT[D.C6][0] = D.A7; MOVE_KNIGHT[D.C6][1] = D.B8; MOVE_KNIGHT[D.C6][2] = D.D8; MOVE_KNIGHT[D.C6][3] = D.E7;
			MOVE_KNIGHT[D.C6][4] = D.E5; MOVE_KNIGHT[D.C6][5] = D.D4; MOVE_KNIGHT[D.C6][6] = D.B4; MOVE_KNIGHT[D.C6][7] = D.A5; MOVE_KNIGHT[D.C6][8] = -1;
		MOVE_KNIGHT[D.D6][0] = D.B7; MOVE_KNIGHT[D.D6][1] = D.C8; MOVE_KNIGHT[D.D6][2] = D.E8; MOVE_KNIGHT[D.D6][3] = D.F7;
			MOVE_KNIGHT[D.D6][4] = D.F5; MOVE_KNIGHT[D.D6][5] = D.E4; MOVE_KNIGHT[D.D6][6] = D.C4; MOVE_KNIGHT[D.D6][7] = D.B5; MOVE_KNIGHT[D.D6][8] = -1;	
		MOVE_KNIGHT[D.E6][0] = D.C7; MOVE_KNIGHT[D.E6][1] = D.D8; MOVE_KNIGHT[D.E6][2] = D.F8; MOVE_KNIGHT[D.E6][3] = D.G7;
			MOVE_KNIGHT[D.E6][4] = D.G5; MOVE_KNIGHT[D.E6][5] = D.F4; MOVE_KNIGHT[D.E6][6] = D.D4; MOVE_KNIGHT[D.E6][7] = D.C5; MOVE_KNIGHT[D.E6][8] = -1;
		MOVE_KNIGHT[D.F6][0] = D.D7; MOVE_KNIGHT[D.F6][1] = D.E8; MOVE_KNIGHT[D.F6][2] = D.G8; MOVE_KNIGHT[D.F6][3] = D.H7;
			MOVE_KNIGHT[D.F6][4] = D.H5; MOVE_KNIGHT[D.F6][5] = D.G4; MOVE_KNIGHT[D.F6][6] = D.E4; MOVE_KNIGHT[D.F6][7] = D.D5; MOVE_KNIGHT[D.F6][8] = -1;		
		MOVE_KNIGHT[D.G6][0] = D.E7; MOVE_KNIGHT[D.G6][1] = D.F8; MOVE_KNIGHT[D.G6][2] = D.H8; MOVE_KNIGHT[D.G6][3] = D.H4;		
			MOVE_KNIGHT[D.G6][4] = D.F4; MOVE_KNIGHT[D.G6][5] = D.E5; MOVE_KNIGHT[D.G6][6] = -1;
		MOVE_KNIGHT[D.H6][0] = D.F7; MOVE_KNIGHT[D.H6][1] = D.G8; MOVE_KNIGHT[D.H6][2] = D.G4; MOVE_KNIGHT[D.H6][3] = D.F5; MOVE_KNIGHT[D.H6][4] = -1;
		
		MOVE_KNIGHT[D.A7][0] = D.C8; MOVE_KNIGHT[D.A7][1] = D.C6; MOVE_KNIGHT[D.A7][2] = D.B5; MOVE_KNIGHT[D.A7][3] = -1;
		MOVE_KNIGHT[D.B7][0] = D.D8; MOVE_KNIGHT[D.B7][1] = D.D6; MOVE_KNIGHT[D.B7][2] = D.C5; MOVE_KNIGHT[D.B7][3] = D.A5; MOVE_KNIGHT[D.B7][4] = -1;
		MOVE_KNIGHT[D.C7][0] = D.E8; MOVE_KNIGHT[D.C7][1] = D.E6; MOVE_KNIGHT[D.C7][2] = D.D5; MOVE_KNIGHT[D.C7][3] = D.B5; 
				MOVE_KNIGHT[D.C7][4] = D.A6; MOVE_KNIGHT[D.C7][5] = D.A8; MOVE_KNIGHT[D.C7][6] = -1;
		MOVE_KNIGHT[D.D7][0] = D.F8; MOVE_KNIGHT[D.D7][1] = D.F6; MOVE_KNIGHT[D.D7][2] = D.E5; MOVE_KNIGHT[D.D7][3] = D.C5; 
				MOVE_KNIGHT[D.D7][4] = D.B6; MOVE_KNIGHT[D.D7][5] = D.B8; MOVE_KNIGHT[D.D7][6] = -1;
		MOVE_KNIGHT[D.E7][0] = D.G8; MOVE_KNIGHT[D.E7][1] = D.G6; MOVE_KNIGHT[D.E7][2] = D.F5; MOVE_KNIGHT[D.E7][3] = D.D5; 
				MOVE_KNIGHT[D.E7][4] = D.C6; MOVE_KNIGHT[D.E7][5] = D.C8; MOVE_KNIGHT[D.E7][6] = -1;
		MOVE_KNIGHT[D.F7][0] = D.H8; MOVE_KNIGHT[D.F7][1] = D.H6; MOVE_KNIGHT[D.F7][2] = D.G5; MOVE_KNIGHT[D.F7][3] = D.E5; 
				MOVE_KNIGHT[D.F7][4] = D.D6; MOVE_KNIGHT[D.F7][5] = D.D8; MOVE_KNIGHT[D.F7][6] = -1;			
		MOVE_KNIGHT[D.G7][0] = D.H5; MOVE_KNIGHT[D.G7][1] = D.F5; MOVE_KNIGHT[D.G7][2] = D.E6; MOVE_KNIGHT[D.G7][3] = D.E8; MOVE_KNIGHT[D.G7][4] = -1;
		MOVE_KNIGHT[D.H7][0] = D.G5; MOVE_KNIGHT[D.H7][1] = D.F6; MOVE_KNIGHT[D.H7][2] = D.F8; MOVE_KNIGHT[D.H7][3] = -1;
		
		MOVE_KNIGHT[D.A8][0] = D.B6; MOVE_KNIGHT[D.A8][1] = D.C7; MOVE_KNIGHT[D.A8][2] = -1;
		MOVE_KNIGHT[D.B8][0] = D.A6; MOVE_KNIGHT[D.B8][1] = D.C6; MOVE_KNIGHT[D.B8][2] = D.D7; MOVE_KNIGHT[D.B8][3] = -1;
		MOVE_KNIGHT[D.C8][0] = D.A7; MOVE_KNIGHT[D.C8][1] = D.B6; MOVE_KNIGHT[D.C8][2] = D.D6; MOVE_KNIGHT[D.C8][3] = D.E7; MOVE_KNIGHT[D.C8][4] = -1;
		MOVE_KNIGHT[D.D8][0] = D.B7; MOVE_KNIGHT[D.D8][1] = D.C6; MOVE_KNIGHT[D.D8][2] = D.E6; MOVE_KNIGHT[D.D8][3] = D.F7; MOVE_KNIGHT[D.D8][4] = -1;
		MOVE_KNIGHT[D.E8][0] = D.C7; MOVE_KNIGHT[D.E8][1] = D.D6; MOVE_KNIGHT[D.E8][2] = D.F6; MOVE_KNIGHT[D.E8][3] = D.G7; MOVE_KNIGHT[D.E8][4] = -1;
		MOVE_KNIGHT[D.F8][0] = D.D7; MOVE_KNIGHT[D.F8][1] = D.E6; MOVE_KNIGHT[D.F8][2] = D.G6; MOVE_KNIGHT[D.F8][3] = D.H7; MOVE_KNIGHT[D.F8][4] = -1;
		MOVE_KNIGHT[D.G8][0] = D.E7; MOVE_KNIGHT[D.G8][1] = D.F6; MOVE_KNIGHT[D.G8][2] = D.H6; MOVE_KNIGHT[D.G8][3] = -1;
		MOVE_KNIGHT[D.H8][0] = D.F7; MOVE_KNIGHT[D.H8][1] = D.G6; MOVE_KNIGHT[D.H8][2] = -1;	
	}
	
	public void generateMoves() {
		moveList.clear();
		// go through all squares
		
	  if (D.WHITE_TO_MOVE == board.sideToMove)		
		for (int i = D.A1; i <= D.H8; i++) {
			switch (board.square[i]) {
				case D.EMPTY:
					break;
				case D.WHITE_PAWN:	
					if (moveUp(i) && isEmpty(i+MOVE_UP_ARRAY[0])) {							
						if (noPawnPromotionSquareForWhite(i+MOVE_UP_ARRAY[0])) {
							Move move = new Move(D.WHITE_PAWN, i, i+MOVE_UP_ARRAY[0], 0, 0, 0);
							moveList.add(move);
						}
						else {
							// promotion
							Move moveQ = new Move(D.WHITE_PAWN, i, i+MOVE_UP_ARRAY[0], 0, 0, D.WHITE_QUEEN);
							moveList.add(moveQ);
							Move moveR = new Move(D.WHITE_PAWN, i, i+MOVE_UP_ARRAY[0], 0, 0, D.WHITE_ROOK);
							moveList.add(moveR);
							Move moveB = new Move(D.WHITE_PAWN, i, i+MOVE_UP_ARRAY[0], 0, 0, D.WHITE_BISHOP);
							moveList.add(moveB);
							Move moveN = new Move(D.WHITE_PAWN, i, i+MOVE_UP_ARRAY[0], 0, 0, D.WHITE_KNIGHT);
							moveList.add(moveN);
						}
													
					}
					if (move2Up(i) && isEmpty(i+MOVE_UP_ARRAY[0]) && isEmpty(i+MOVE_UP_ARRAY[1])) {
						Move move = new Move(D.WHITE_PAWN, i, i+MOVE_UP_ARRAY[1], 0, 0, 0);
						moveList.add(move);
					}
					if (moveDiagUpperRight(i) && isBlackPiece(board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0]]) && positivFileDifference(i, MOVE_DIAG_UPPER_RIGHT_ARRAY[0])) {
						if (noPawnPromotionSquareForWhite(i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0])) {
							Move move = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0], board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0]], 0, 0);
							moveList.add(move);
						}
						else {
							// promotion
							Move moveQ = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0], board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0]], 0, D.WHITE_QUEEN);
							moveList.add(moveQ);
							Move moveR = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0], board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0]], 0, D.WHITE_ROOK);
							moveList.add(moveR);
							Move moveB = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0], board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0]], 0, D.WHITE_BISHOP);
							moveList.add(moveB);
							Move moveN = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0], board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0]], 0, D.WHITE_KNIGHT);
							moveList.add(moveN);
						}
					}
					if (moveDiagUpperLeft(i) && isBlackPiece(board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[0]]) && !positivFileDifference(i, MOVE_DIAG_UPPER_LEFT_ARRAY[0])) {
						if (noPawnPromotionSquareForWhite(i+MOVE_DIAG_UPPER_LEFT_ARRAY[0])) {
							Move move = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[0], board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[0]], 0, 0);
							moveList.add(move);
						}
						else {
							// promotion
							Move moveQ = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[0], board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[0]], 0, D.WHITE_QUEEN);
							moveList.add(moveQ);
							Move moveR = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[0], board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[0]], 0, D.WHITE_ROOK);
							moveList.add(moveR);
							Move moveB = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[0], board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[0]], 0, D.WHITE_BISHOP);
							moveList.add(moveB);
							Move moveN = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[0], board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[0]], 0, D.WHITE_KNIGHT);
							moveList.add(moveN);
						}
					}
					if (i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0] == board.enPassantSquare && positivFileDifference(i, MOVE_DIAG_UPPER_RIGHT_ARRAY[0]) && i >= D.A5) {
						Move move = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[0], D.BLACK_PAWN, 0, 0);
						moveList.add(move);
					}
					if (i+MOVE_DIAG_UPPER_LEFT_ARRAY[0] == board.enPassantSquare && !positivFileDifference(i, MOVE_DIAG_UPPER_LEFT_ARRAY[0]) && i >= D.A5) {
						Move move = new Move(D.WHITE_PAWN, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[0], D.BLACK_PAWN, 0, 0);
						moveList.add(move);
					}
					break;
				case D.WHITE_KNIGHT:
					int m = 0;
					while (MOVE_KNIGHT[i][m] > 0) {
						if (board.square[MOVE_KNIGHT[i][m]] == D.EMPTY) {
							Move move = new Move(D.WHITE_KNIGHT, i, MOVE_KNIGHT[i][m], 0, 0, 0);
							moveList.add(move);
						}
						if (isBlackPiece(board.square[MOVE_KNIGHT[i][m]])) {
							Move moveC = new Move(D.WHITE_KNIGHT, i, MOVE_KNIGHT[i][m], board.square[MOVE_KNIGHT[i][m]], 0, 0);
							moveList.add(moveC);
						}
						m++;
					}								
					break;
 					
				case D.WHITE_ROOK:
					for (int r = 0; r < MOVE_UP_ARRAY.length; r++)
						if (moveValid(i, MOVE_UP_ARRAY[r])) {
							if ((board.square[i+MOVE_UP_ARRAY[r]] == D.EMPTY)) {
								Move move = new Move(D.WHITE_ROOK, i, i+MOVE_UP_ARRAY[r], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_UP_ARRAY[r]])) {
								Move moveC = new Move(D.WHITE_ROOK, i, i+MOVE_UP_ARRAY[r], board.square[i+MOVE_UP_ARRAY[r]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_UP_ARRAY[r]])) {
								break;
							}
						}
					for (int r = 0; r < MOVE_DOWN_ARRAY.length; r++)
						if (moveValid(i, MOVE_DOWN_ARRAY[r])) {
							if ((board.square[i+MOVE_DOWN_ARRAY[r]] == D.EMPTY)) {
								Move move = new Move(D.WHITE_ROOK, i, i+MOVE_DOWN_ARRAY[r], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_DOWN_ARRAY[r]])) {
								Move moveC = new Move(D.WHITE_ROOK, i, i+MOVE_DOWN_ARRAY[r], board.square[i+MOVE_DOWN_ARRAY[r]], 0, 0);
								moveList.add(moveC);
								// move DOWN is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_DOWN_ARRAY[r]])) {
								break;
							}
						}				
					// horizontal moves - right side
					int r = 1;
					while (moveValid(i, r) && sameRank(i, r)) {
						if (board.square[i+r] == D.EMPTY)  {
							Move move = new Move(D.WHITE_ROOK, i, i+r, 0, 0, 0);
							moveList.add(move);
						}
						if (isBlackPiece(board.square[i+r])) {
							Move moveC = new Move(D.WHITE_ROOK, i, i+r, board.square[i+r], 0, 0);
							moveList.add(moveC);
							// move RIGHT is blocked now by black piece
							break;
						}
						if (isWhitePiece(board.square[i+r])) {
							break;
						}
						r++;
					}
					// horizontal moves - left side
					r = -1;
					while (moveValid(i, r) && sameRank(i, r)) {
						if (board.square[i+r] == D.EMPTY)  {
							Move move = new Move(D.WHITE_ROOK, i, i+r, 0, 0, 0);
							moveList.add(move);
						}
						if (isBlackPiece(board.square[i+r])) {
							Move moveC = new Move(D.WHITE_ROOK, i, i+r, board.square[i+r], 0, 0);
							moveList.add(moveC);
							// move LEFT is blocked now by black piece
							break;
						}
						if (isWhitePiece(board.square[i+r])) {
							break;
						}
						r--;
					}
					break;
					
				case D.WHITE_BISHOP:
					for (int b = 0; b < MOVE_DIAG_UPPER_RIGHT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_UPPER_RIGHT_ARRAY[b]) && positivFileDifference(i, MOVE_DIAG_UPPER_RIGHT_ARRAY[b])) {
							if (board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.WHITE_BISHOP, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]])) {
								Move moveC = new Move(D.WHITE_BISHOP, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b], board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_LOWER_RIGHT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_LOWER_RIGHT_ARRAY[b]) && positivFileDifference(i, MOVE_DIAG_LOWER_RIGHT_ARRAY[b])) {
							if (board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.WHITE_BISHOP, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]])) {
								Move moveC = new Move(D.WHITE_BISHOP, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b], board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_UPPER_LEFT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_UPPER_LEFT_ARRAY[b]) && !positivFileDifference(i, MOVE_DIAG_UPPER_LEFT_ARRAY[b])) {
							if (board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.WHITE_BISHOP, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]])) {
								Move moveC = new Move(D.WHITE_BISHOP, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[b], board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_LOWER_LEFT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_LOWER_LEFT_ARRAY[b]) && !positivFileDifference(i, MOVE_DIAG_LOWER_LEFT_ARRAY[b])) {
							if (board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.WHITE_BISHOP, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]])) {
								Move moveC = new Move(D.WHITE_BISHOP, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[b], board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]])) {
								break;
							}
						}					
					break;
				case D.WHITE_QUEEN:
					for (int b = 0; b < MOVE_DIAG_UPPER_RIGHT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_UPPER_RIGHT_ARRAY[b]) && positivFileDifference(i, MOVE_DIAG_UPPER_RIGHT_ARRAY[b]))  {
							if (board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.WHITE_QUEEN, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]])) {
								Move moveC = new Move(D.WHITE_QUEEN, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b], board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_LOWER_RIGHT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_LOWER_RIGHT_ARRAY[b]) && positivFileDifference(i, MOVE_DIAG_LOWER_RIGHT_ARRAY[b]))  {
							if (board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.WHITE_QUEEN, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]])) {
								Move moveC = new Move(D.WHITE_QUEEN, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b], board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_UPPER_LEFT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_UPPER_LEFT_ARRAY[b]) && !positivFileDifference(i, MOVE_DIAG_UPPER_LEFT_ARRAY[b]))  {
							if (board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.WHITE_QUEEN, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]])) {
								Move moveC = new Move(D.WHITE_QUEEN, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[b], board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_LOWER_LEFT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_LOWER_LEFT_ARRAY[b]) && !positivFileDifference(i, MOVE_DIAG_LOWER_LEFT_ARRAY[b]))  {
							if (board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.WHITE_QUEEN, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]])) {
								Move moveC = new Move(D.WHITE_QUEEN, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[b], board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]])) {
								break;
							}
						}					
					//  vertical
					for (r = 0; r < MOVE_UP_ARRAY.length; r++)
						if (moveValid(i, MOVE_UP_ARRAY[r])) {
							if ((board.square[i+MOVE_UP_ARRAY[r]] == D.EMPTY)) {
								Move move = new Move(D.WHITE_QUEEN, i, i+MOVE_UP_ARRAY[r], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_UP_ARRAY[r]])) {
								Move moveC = new Move(D.WHITE_QUEEN, i, i+MOVE_UP_ARRAY[r], board.square[i+MOVE_UP_ARRAY[r]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_UP_ARRAY[r]])) {
								break;
							}
						}
					for (r = 0; r < MOVE_DOWN_ARRAY.length; r++)
						if (moveValid(i, MOVE_DOWN_ARRAY[r])) {
							if ((board.square[i+MOVE_DOWN_ARRAY[r]] == D.EMPTY)) {
								Move move = new Move(D.WHITE_QUEEN, i, i+MOVE_DOWN_ARRAY[r], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[i+MOVE_DOWN_ARRAY[r]])) {
								Move moveC = new Move(D.WHITE_QUEEN, i, i+MOVE_DOWN_ARRAY[r], board.square[i+MOVE_DOWN_ARRAY[r]], 0, 0);
								moveList.add(moveC);
								// move DOWN is blocked now by black piece
								break;
							}
							if (isWhitePiece(board.square[i+MOVE_DOWN_ARRAY[r]])) {
								break;
							}
						}				
					// horizontal moves - right side
					r = 1;
					while (moveValid(i, r) && sameRank(i, r)) {
						if (board.square[i+r] == D.EMPTY)  {
							Move move = new Move(D.WHITE_QUEEN, i, i+r, 0, 0, 0);
							moveList.add(move);
						}
						if (isBlackPiece(board.square[i+r])) {
							Move moveC = new Move(D.WHITE_QUEEN, i, i+r, board.square[i+r], 0, 0);
							moveList.add(moveC);
							// move RIGHT is blocked now by black piece
							break;
						}
						if (isWhitePiece(board.square[i+r])) {
							break;
						}
						r++;
					}
					// horizontal moves - left side
					r = -1;
					while (moveValid(i, r) && sameRank(i, r)) {
						if (board.square[i+r] == D.EMPTY)  {
							Move move = new Move(D.WHITE_QUEEN, i, i+r, 0, 0, 0);
							moveList.add(move);
						}
						if (isBlackPiece(board.square[i+r])) {
							Move moveC = new Move(D.WHITE_QUEEN, i, i+r, board.square[i+r], 0, 0);
							moveList.add(moveC);
							// move LEFT is blocked now by black piece
							break;
						}
						if (isWhitePiece(board.square[i+r])) {
							break;
						}
						r--;
					}
					break;
				case D.WHITE_KING:
					// normal moves to squares around
					// normal moves to squares around
					m = 0;
					while (MOVE_KING[i][m] > 0) {
							if (board.square[MOVE_KING[i][m]] == D.EMPTY)  {
								Move move = new Move(D.WHITE_KING, i, MOVE_KING[i][m], 0, 0, 0);
								moveList.add(move);
							}
							if (isBlackPiece(board.square[MOVE_KING[i][m]])) {
								Move moveC = new Move(D.WHITE_KING, i, MOVE_KING[i][m], board.square[MOVE_KING[i][m]], 0, 0);
								moveList.add(moveC);
							}
							m++;
					}
					
					// rochades
					if (i == D.E1 && board.whiteCanCastle00) {
						if ((board.square[D.F1] == D.EMPTY) && (board.square[D.G1] == D.EMPTY) &&							
						(notAttacked(board.square[D.E1], board.sideToMove) && notAttacked(board.square[D.F1], board.sideToMove) 
								&& notAttacked(board.square[D.G1], board.sideToMove) )
								&& board.square[D.H1] == D.WHITE_ROOK) {
							Move move = new Move(D.WHITE_KING, D.E1, D.G1, 0, D.WHITE_CASTLING_00, 0);
							moveList.add(move);
						}
					}
					if (i == D.E1 && board.whiteCanCastle000) {
						if ((board.square[D.D1] == D.EMPTY) && (board.square[D.C1] == D.EMPTY)  && (board.square[D.B1] == D.EMPTY) &&							
						(notAttacked(board.square[D.E1], board.sideToMove) && notAttacked(board.square[D.D1], board.sideToMove) 
								&& notAttacked(board.square[D.C1], board.sideToMove) )
								&& board.square[D.A1] == D.WHITE_ROOK) {
							Move move = new Move(D.WHITE_KING, D.E1, D.C1, 0, D.WHITE_CASTLING_000, 0); 
							moveList.add(move);
						}
					}
					break;
			}
		}
		else
		  for (int i = D.A1; i <= D.H8; i++) {
			  switch (board.square[i]) {	
				case D.BLACK_PAWN:	
					if (moveDown(i) && isEmpty(i+MOVE_DOWN_ARRAY[0])) {							
						if (noPawnPromotionSquareForBlack(i+MOVE_DOWN_ARRAY[0])) {
							Move move = new Move(D.BLACK_PAWN, i, i+MOVE_DOWN_ARRAY[0], 0, 0, 0);
							moveList.add(move);
						}
						else {
							// promotion
							Move moveQ = new Move(D.BLACK_PAWN, i, i+MOVE_DOWN_ARRAY[0], 0, 0, D.BLACK_QUEEN);
							moveList.add(moveQ);
							Move moveR = new Move(D.BLACK_PAWN, i, i+MOVE_DOWN_ARRAY[0], 0, 0, D.BLACK_ROOK);
							moveList.add(moveR);
							Move moveB = new Move(D.BLACK_PAWN, i, i+MOVE_DOWN_ARRAY[0], 0, 0, D.BLACK_BISHOP);
							moveList.add(moveB);
							Move moveN = new Move(D.BLACK_PAWN, i, i+MOVE_DOWN_ARRAY[0], 0, 0, D.BLACK_KNIGHT);
							moveList.add(moveN);
						}
													
					}
					if (move2Down(i) && isEmpty(i+MOVE_DOWN_ARRAY[0]) && isEmpty(i+MOVE_DOWN_ARRAY[1])) {
						Move move = new Move(D.BLACK_PAWN, i, i+MOVE_DOWN_ARRAY[1], 0, 0, 0);
						moveList.add(move);
					}
					if (moveDiagLowerRight(i) && isWhitePiece(board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0]]) && positivFileDifference(i, MOVE_DIAG_LOWER_RIGHT_ARRAY[0])) {
						if (noPawnPromotionSquareForBlack(i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0])) {
							Move move = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0], board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0]], 0, 0);
							moveList.add(move);
						}
						else {
							// promotion
							Move moveQ = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0], board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0]], 0, D.BLACK_QUEEN);
							moveList.add(moveQ);
							Move moveR = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0], board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0]], 0, D.BLACK_ROOK);
							moveList.add(moveR);
							Move moveB = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0], board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0]], 0, D.BLACK_BISHOP);
							moveList.add(moveB);
							Move moveN = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0], board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0]], 0, D.BLACK_KNIGHT);
							moveList.add(moveN);
						}
					}
					if (moveDiagLowerLeft(i) && isWhitePiece(board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[0]]) && !positivFileDifference(i, MOVE_DIAG_LOWER_LEFT_ARRAY[0])) {
						if (noPawnPromotionSquareForBlack(i+MOVE_DIAG_LOWER_LEFT_ARRAY[0])) {
							Move move = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[0], board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[0]], 0, 0);
							moveList.add(move);
						}
						else {
							// promotion
							Move moveQ = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[0], board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[0]], 0, D.BLACK_QUEEN);
							moveList.add(moveQ);
							Move moveR = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[0], board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[0]], 0, D.BLACK_ROOK);
							moveList.add(moveR);
							Move moveB = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[0], board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[0]], 0, D.BLACK_BISHOP);
							moveList.add(moveB);
							Move moveN = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[0], board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[0]], 0, D.BLACK_KNIGHT);
							moveList.add(moveN);
						}
					}					
					if (i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0] == board.enPassantSquare && positivFileDifference(i, MOVE_DIAG_LOWER_RIGHT_ARRAY[0]) && i <= D.H4) {
						Move move = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[0], D.WHITE_PAWN, 0, 0);
						moveList.add(move);
					}
					if (i+MOVE_DIAG_LOWER_LEFT_ARRAY[0] == board.enPassantSquare && !positivFileDifference(i, MOVE_DIAG_LOWER_LEFT_ARRAY[0]) && i <= D.H4) {
						Move move = new Move(D.BLACK_PAWN, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[0], D.WHITE_PAWN, 0, 0);
						moveList.add(move);
					}
					break;
				case D.BLACK_KNIGHT:
					int m = 0;
					while (MOVE_KNIGHT[i][m] > 0) {
						if (board.square[MOVE_KNIGHT[i][m]] == D.EMPTY) {
							Move move = new Move(D.BLACK_KNIGHT, i, MOVE_KNIGHT[i][m], 0, 0, 0);
							moveList.add(move);
						}
						if (isWhitePiece(board.square[MOVE_KNIGHT[i][m]])) {
							Move moveC = new Move(D.BLACK_KNIGHT, i, MOVE_KNIGHT[i][m], board.square[MOVE_KNIGHT[i][m]], 0, 0);
							moveList.add(moveC);
						}
						m++;
					}								
					break;
					
				case D.BLACK_ROOK:
					for (int r = 0; r < MOVE_UP_ARRAY.length; r++)
						if (moveValid(i, MOVE_UP_ARRAY[r])) {
							if ((board.square[i+MOVE_UP_ARRAY[r]] == D.EMPTY)) {
								Move move = new Move(D.BLACK_ROOK, i, i+MOVE_UP_ARRAY[r], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_UP_ARRAY[r]])) {
								Move moveC = new Move(D.BLACK_ROOK, i, i+MOVE_UP_ARRAY[r], board.square[i+MOVE_UP_ARRAY[r]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_UP_ARRAY[r]])) {
								break;
							}
						}
					for (int r = 0; r < MOVE_DOWN_ARRAY.length; r++)
						if (moveValid(i, MOVE_DOWN_ARRAY[r])) {
							if ((board.square[i+MOVE_DOWN_ARRAY[r]] == D.EMPTY)) {
								Move move = new Move(D.BLACK_ROOK, i, i+MOVE_DOWN_ARRAY[r], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_DOWN_ARRAY[r]])) {
								Move moveC = new Move(D.BLACK_ROOK, i, i+MOVE_DOWN_ARRAY[r], board.square[i+MOVE_DOWN_ARRAY[r]], 0, 0);
								moveList.add(moveC);
								// move DOWN is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_DOWN_ARRAY[r]])) {
								break;
							}
						}				
					// horizontal moves - right side
					int r = 1;
					while (moveValid(i, r) && sameRank(i, r)) {
						if (board.square[i+r] == D.EMPTY)  {
							Move move = new Move(D.BLACK_ROOK, i, i+r, 0, 0, 0);
							moveList.add(move);
						}
						if (isWhitePiece(board.square[i+r])) {
							Move moveC = new Move(D.BLACK_ROOK, i, i+r, board.square[i+r], 0, 0);
							moveList.add(moveC);
							// move RIGHT is blocked now by black piece
							break;
						}
						if (isBlackPiece(board.square[i+r])) {
							break;
						}
						r++;
					}
					// horizontal moves - left side
					r = -1;
					while (moveValid(i, r) && sameRank(i, r)) {
						if (board.square[i+r] == D.EMPTY)  {
							Move move = new Move(D.BLACK_ROOK, i, i+r, 0, 0, 0);
							moveList.add(move);
						}
						if (isWhitePiece(board.square[i+r])) {
							Move moveC = new Move(D.BLACK_ROOK, i, i+r, board.square[i+r], 0, 0);
							moveList.add(moveC);
							// move LEFT is blocked now by black piece
							break;
						}
						if (isBlackPiece(board.square[i+r])) {
							break;
						}
						r--;
					}
					break;
					
				case D.BLACK_BISHOP:
					for (int b = 0; b < MOVE_DIAG_UPPER_RIGHT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_UPPER_RIGHT_ARRAY[b]) && positivFileDifference(i, MOVE_DIAG_UPPER_RIGHT_ARRAY[b]))  {
							if (board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.BLACK_BISHOP, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]])) {
								Move moveC = new Move(D.BLACK_BISHOP, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b], board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_LOWER_RIGHT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_LOWER_RIGHT_ARRAY[b]) && positivFileDifference(i, MOVE_DIAG_LOWER_RIGHT_ARRAY[b]))  {
							if (board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.BLACK_BISHOP, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]])) {
								Move moveC = new Move(D.BLACK_BISHOP, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b], board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_UPPER_LEFT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_UPPER_LEFT_ARRAY[b]) && !positivFileDifference(i, MOVE_DIAG_UPPER_LEFT_ARRAY[b])) {
							if (board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.BLACK_BISHOP, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]])) {
								Move moveC = new Move(D.BLACK_BISHOP, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[b], board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_LOWER_LEFT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_LOWER_LEFT_ARRAY[b]) && !positivFileDifference(i, MOVE_DIAG_LOWER_LEFT_ARRAY[b]))  {
							if (board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.BLACK_BISHOP, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]])) {
								Move moveC = new Move(D.BLACK_BISHOP, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[b], board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]])) {
								break;
							}
						}					
					break;
				case D.BLACK_QUEEN:
					for (int b = 0; b < MOVE_DIAG_UPPER_RIGHT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_UPPER_RIGHT_ARRAY[b]) && positivFileDifference(i, MOVE_DIAG_UPPER_RIGHT_ARRAY[b])) {
							if (board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.BLACK_QUEEN, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]])) {
								Move moveC = new Move(D.BLACK_QUEEN, i, i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b], board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_UPPER_RIGHT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_LOWER_RIGHT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_LOWER_RIGHT_ARRAY[b]) && positivFileDifference(i, MOVE_DIAG_LOWER_RIGHT_ARRAY[b]))  {
							if (board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.BLACK_QUEEN, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]])) {
								Move moveC = new Move(D.BLACK_QUEEN, i, i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b], board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_LOWER_RIGHT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_UPPER_LEFT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_UPPER_LEFT_ARRAY[b]) && !positivFileDifference(i, MOVE_DIAG_UPPER_LEFT_ARRAY[b])) {
							if (board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.BLACK_QUEEN, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]])) {
								Move moveC = new Move(D.BLACK_QUEEN, i, i+MOVE_DIAG_UPPER_LEFT_ARRAY[b], board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_UPPER_LEFT_ARRAY[b]])) {
								break;
							}
						}
					for (int b = 0; b < MOVE_DIAG_LOWER_LEFT_ARRAY.length; b++)
						if (moveValid(i, MOVE_DIAG_LOWER_LEFT_ARRAY[b]) && !positivFileDifference(i, MOVE_DIAG_LOWER_LEFT_ARRAY[b]))  {
							if (board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]] == D.EMPTY)  {
								Move move = new Move(D.BLACK_QUEEN, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[b], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]])) {
								Move moveC = new Move(D.BLACK_QUEEN, i, i+MOVE_DIAG_LOWER_LEFT_ARRAY[b], board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_DIAG_LOWER_LEFT_ARRAY[b]])) {
								break;
							}
						}					
					//  vertical
					for (r = 0; r < MOVE_UP_ARRAY.length; r++)
						if (moveValid(i, MOVE_UP_ARRAY[r])) {
							if ((board.square[i+MOVE_UP_ARRAY[r]] == D.EMPTY)) {
								Move move = new Move(D.BLACK_QUEEN, i, i+MOVE_UP_ARRAY[r], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_UP_ARRAY[r]])) {
								Move moveC = new Move(D.BLACK_QUEEN, i, i+MOVE_UP_ARRAY[r], board.square[i+MOVE_UP_ARRAY[r]], 0, 0);
								moveList.add(moveC);
								// move up is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_UP_ARRAY[r]])) {
								break;
							}
						}
					for (r = 0; r < MOVE_DOWN_ARRAY.length; r++)
						if (moveValid(i, MOVE_DOWN_ARRAY[r])) {
							if ((board.square[i+MOVE_DOWN_ARRAY[r]] == D.EMPTY)) {
								Move move = new Move(D.BLACK_QUEEN, i, i+MOVE_DOWN_ARRAY[r], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[i+MOVE_DOWN_ARRAY[r]])) {
								Move moveC = new Move(D.BLACK_QUEEN, i, i+MOVE_DOWN_ARRAY[r], board.square[i+MOVE_DOWN_ARRAY[r]], 0, 0);
								moveList.add(moveC);
								// move DOWN is blocked now by black piece
								break;
							}
							if (isBlackPiece(board.square[i+MOVE_DOWN_ARRAY[r]])) {
								break;
							}
						}				
					// horizontal moves - right side
					r = 1;
					while (moveValid(i, r) && sameRank(i, r)) {
						if (board.square[i+r] == D.EMPTY)  {
							Move move = new Move(D.BLACK_QUEEN, i, i+r, 0, 0, 0);
							moveList.add(move);
						}
						if (isWhitePiece(board.square[i+r])) {
							Move moveC = new Move(D.BLACK_QUEEN, i, i+r, board.square[i+r], 0, 0);
							moveList.add(moveC);
							// move RIGHT is blocked now by black piece
							break;
						}
						if (isBlackPiece(board.square[i+r])) {
							break;
						}
						r++;
					}
					// horizontal moves - left side
					r = -1;
					while (moveValid(i, r) && sameRank(i, r)) {
						if (board.square[i+r] == D.EMPTY)  {
							Move move = new Move(D.BLACK_QUEEN, i, i+r, 0, 0, 0);
							moveList.add(move);
						}
						if (isWhitePiece(board.square[i+r])) {
							Move moveC = new Move(D.BLACK_QUEEN, i, i+r, board.square[i+r], 0, 0);
							moveList.add(moveC);
							// move LEFT is blocked now by black piece
							break;
						}
						if (isBlackPiece(board.square[i+r])) {
							break;
						}
						r--;
					}
					break;
				case D.BLACK_KING:
					// normal moves to squares around
					m = 0;
					while (MOVE_KING[i][m] > 0) {
							if (board.square[MOVE_KING[i][m]] == D.EMPTY)  {
								Move move = new Move(D.BLACK_KING, i, MOVE_KING[i][m], 0, 0, 0);
								moveList.add(move);
							}
							if (isWhitePiece(board.square[MOVE_KING[i][m]])) {
								Move moveC = new Move(D.BLACK_KING, i, MOVE_KING[i][m], board.square[MOVE_KING[i][m]], 0, 0);
								moveList.add(moveC);
							}
							m++;
					}
					
					// rochades
					if (i == D.E8 && board.blackCanCastle00) {
						if ((board.square[D.F8] == D.EMPTY) && (board.square[D.G8] == D.EMPTY) &&							
						(notAttacked(board.square[D.E8], board.sideToMove) && notAttacked(board.square[D.F8], board.sideToMove) 
								&& notAttacked(board.square[D.G8], board.sideToMove) )
								&& board.square[D.H8] == D.BLACK_ROOK) {
							Move move = new Move(D.BLACK_KING, D.E8, D.G8, 0, D.BLACK_CASTLING_00, 0);
							moveList.add(move);
						}
					}
					if (i == D.E8 && board.blackCanCastle000) {
						if ((board.square[D.D8] == D.EMPTY) && (board.square[D.C8] == D.EMPTY)  && (board.square[D.B8] == D.EMPTY) &&							
						(notAttacked(board.square[D.E8], board.sideToMove) && notAttacked(board.square[D.D8], board.sideToMove) 
								&& notAttacked(board.square[D.C8], board.sideToMove) )
								&& board.square[D.A8] == D.BLACK_ROOK) {
							Move move = new Move(D.BLACK_KING, D.E8, D.C8, 0, D.BLACK_CASTLING_000, 0); 
							moveList.add(move);
						}
					}
					break;
						
				
				}
			
		}
		
	}
	

//	// attacked squares
//	// pawns
//	public int[] pawnAttacks() {
//		for (int i = A1; i < H8; i++) {
//			switch (board.square[i]) {
//				case DEF.WHITE_PAWN:
//					board.wP_attacks[i] = true;
//					break;
//
//			default:
//				break;
//			} 
//			
//		}
//		
//		
//		return null;
//	}
	

	// for debug purposes - show or output all generated moves
	public void displayMoves() {
		System.out.print("Total nb of moves : "); System.out.println(moveList.size());
		for (Move move : moveList) {
			System.out.println(D.pieceName[move.piece + 6] + " from " + D.squareName[move.from] + " to "+ D.squareName[move.to]); 
		}
	}
	

}


